package com.job.client.message.service.impl;

import com.alibaba.fastjson2.JSON;
import com.job.client.common.minio.BucketNameConstant;
import com.job.client.common.minio.MinIOUtils;

import com.job.client.common.result.AppHttpCode;
import com.job.client.common.result.ResponseResult;

import com.job.client.common.utils.DateTimeUtils;
import com.job.client.message.constant.MessageConstant;
import com.job.client.model.message.constant.XxlJobConstant;
import com.job.client.message.pojo.ConnectItem;
import com.job.client.message.pojo.Message;
import com.job.client.message.pojo.MessageItem;
import com.job.client.message.service.MessageService;
import com.job.client.model.message.constant.ChatLogRabbitmqConstant;

import com.job.feign.webSocket.WebSocketFeign;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Slf4j
public class MessageServiceImpl implements MessageService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private WebSocketFeign webSocketFeign;

    @Override
    public ResponseResult createMessage(String messageId) {
        if(messageId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Message message =new Message();
        message.setUserId(messageId);

        List<ConnectItem> connectItemList = new ArrayList<>();
        ConnectItem connectItem =new ConnectItem();
        connectItem.setUserId(MessageConstant.BOSS_CONNECT_ID);
        connectItem.setPostsId(MessageConstant.BOSS_POSTS_ID);

        List<MessageItem> messageItemList = new ArrayList<>();
        MessageItem messageItem =new MessageItem();
        messageItem.setTime(DateTimeUtils.createNowTime());
        messageItem.setType(MessageConstant.MESSAGE_TYPE_TEXT);
        messageItem.setContent(MessageConstant.BOSS_INIT_MESSAGE);
        messageItem.setStatus(MessageConstant.CONTENT_OTHER_STATUS);
        messageItemList.add(messageItem);

        connectItem.setMessage(messageItemList);
        connectItem.setNumber(MessageConstant.NUMBER_INIT);
        connectItemList.add(connectItem);

        message.setConnect(connectItemList);

        mongoTemplate.save(message);
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult createConnect(String messageId,String connectId,String postsId) {
        if(messageId == null || connectId == null || postsId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }

        // 初始化自己的会话
        MessageItem messageItem  = new MessageItem(DateTimeUtils.createNowTime(),
                MessageConstant.MESSAGE_TYPE_TEXT,
                MessageConstant.INIT_MESSAGE,
                MessageConstant.CONTENT_MYSELF_STATUS);
        List<MessageItem> messageItemList = new ArrayList<>();
        messageItemList.add(messageItem);
        ConnectItem connectItem = new ConnectItem(connectId,postsId,messageItemList);
        connectItem.setNumber(MessageConstant.NUMBER_CLEAR);

        Query query = new Query(Criteria.where("user_id").is(messageId));
        Update update = new Update().push("connect", connectItem);
        mongoTemplate.findAndModify(query, update, Message.class);

        // 初始化别人的会话
        messageItem.setStatus(MessageConstant.CONTENT_OTHER_STATUS);
        messageItemList.clear();
        messageItemList.add(messageItem);
        ConnectItem connectItem1 = new ConnectItem(messageId,postsId,messageItemList);
        connectItem1.setNumber(MessageConstant.NUMBER_INIT);
        Query query1 = new Query(Criteria.where("user_id").is(connectId));
        Update update1 = new Update().push("connect", connectItem1);
        mongoTemplate.findAndModify(query1, update1, Message.class);

        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult saveMessage(MessageItem messageItem, String messageId, String connectId) {
        if(messageItem == null || messageId == null || connectId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Map<String,Object> data = new HashMap<>();
        data.put("messageItem",messageItem);
        data.put("messageId",messageId);
        data.put("connectId",connectId);
        if(MessageConstant.BOSS_CONNECT_ID.equals(connectId) && MessageConstant.CONTENT_MYSELF_STATUS.equals(messageItem.getStatus())){
            rabbitTemplate.convertAndSend(ChatLogRabbitmqConstant.EXCHANGE_CHAT_LOG,
                    ChatLogRabbitmqConstant.ROUTINGKEY_CHAT_LOG_ADMIN,
                    JSON.toJSONString(data));
        }
            rabbitTemplate.convertAndSend(ChatLogRabbitmqConstant.EXCHANGE_CHAT_LOG,
                    ChatLogRabbitmqConstant.ROUTINGKEY_CHAT_LOG_MESSAGE,
                    JSON.toJSONString(data));
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult getById(String userId) {
        if(userId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        //设置查询条件
        Criteria criteria = Criteria.where("user_id").is(userId);
        //设置查询条件
        Query query = new Query(criteria);
        //查询
        Message message = mongoTemplate.findOne(query, Message.class);
        if(message == null){
            return ResponseResult.ErrorResult(AppHttpCode.MONGODB_DATA_NULL);
        }
        return ResponseResult.OkResult(message);

    }

    @Override
    public ResponseResult deleteById(String userId) {
        if(userId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Criteria criteria = Criteria.where("user_id").is(userId);
        Query query = new Query(criteria);
        mongoTemplate.remove(query);
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult uploadAvatar(MultipartFile file, HttpServletRequest request) {
        if(file==null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        String[] split = file.getOriginalFilename().split("\\.");
        String contentType = split[split.length-1];
        String uuid = String.valueOf(UUID.randomUUID());  //使用uuid获得文件的扩展名
        String fileName = uuid+"."+contentType;
        try {
            MinIOUtils.uploadFile(BucketNameConstant.CLIENT_MESSAGE_IMG,file,fileName,contentType);  //反斜杠是一个转义字符，所以需要使用两个反斜杠来表示一个实际的点
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseResult.ErrorResult(AppHttpCode.MINIO_UPLOAD_FAIL);
        }
        String imgURL = MinIOUtils.getBasisUrl(BucketNameConstant.CLIENT_MESSAGE_IMG, fileName);

        return ResponseResult.OkResult(imgURL);
    }

    @Override
    public ResponseResult connectIsExist(String messageId, String connectId,String postsId) {
        if(messageId == null || connectId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Query query = new Query(Criteria.where("user_id").is(messageId)
                .and("connect.user_id").is(connectId));
        Message message = mongoTemplate.findOne(query, Message.class);
        if(message == null){
            ResponseResult result = createConnect(messageId, connectId, postsId);
            if(result.getCode() != 200){
                return result;
            }
        }
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult clearNumber(String messageId, String connectId) {
        if(messageId == null || connectId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Query query = new Query(Criteria.where("user_id").is(messageId)
                .and("connect.user_id").is(connectId));
        Update update = new Update();
        update.set("connect.$.number",MessageConstant.NUMBER_CLEAR);
        //查询
        mongoTemplate.updateFirst(query,update,Message.class);
        return ResponseResult.OkResult();
    }

    // 推送消息到webSocket
    public void pushMessage(String cid,String data){
        ResponseResult result = webSocketFeign.pushMessage(cid, data);
        if(result.getCode() != 200){
            log.error("webSocket推送到客户端消息失败");
        }
    }
// 清除超过30天的聊天记录
    @Override
    @XxlJob(XxlJobConstant.CLEAN_MESSAGE)
    public void cleanMessage() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date(); // 获取当前时间
        Date threshold = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000); // 设置30天前的日期
        List<Message> all = mongoTemplate.findAll(Message.class);
        List<Message> newMessageList = new ArrayList<>();
        for (Message message : all) {
            List<ConnectItem> connectItems = message.getConnect();
            List<ConnectItem> newConnectItems = new ArrayList<>();
            for (ConnectItem connectItem : connectItems) {
                List<MessageItem> messageItems = connectItem.getMessage();
                List<MessageItem> newMessageItems = new ArrayList<>();
                for (MessageItem messageItem : messageItems) {
                    try {
                        if(!threshold.after(sdf.parse(messageItem.getTime()))){
                            newMessageItems.add(messageItem);
                        }
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
                newConnectItems.add(new ConnectItem(connectItem.getUserId(),connectItem.getPostsId(),connectItem.getNumber(),newMessageItems));
            }
            newMessageList.add(new Message(message.getId(),message.getUserId(),newConnectItems));
        }
        mongoTemplate.remove(new Query(),Message.class);
        mongoTemplate.insertAll(newMessageList);
    }
}